// Copyright (c) Cyrus J. Kalbrener
package edu.mit.csail.relo.jdt.builder;

import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.openrdf.model.Resource;

import edu.mit.csail.relo.ReloCore;
import edu.mit.csail.relo.jdt.RJCore;
import edu.mit.csail.relo.modelBridge.Artifact;
import edu.mit.csail.relo.store.ReloRdfRepository;

/**
 * @author Cyrus J. Kalbrener
 */
// TODO: add real JavaDoc to this class
public abstract class ReloBuildVisitor implements IResourceDeltaVisitor, IResourceVisitor {

    protected IProgressMonitor monitor;
    public void setMonitor(IProgressMonitor monitor) {
        this.monitor = monitor;
        monitor.beginTask("Parse for Relo", taskSize);
    }

    protected int taskSize;
    protected int taskDone;
    public int getTaskSize() {
        return taskSize;
    }
    public void setTaskSize(int taskSize) {
        this.taskSize = taskSize;
    }

    protected ReloRdfRepository reloRdf;
    public void setRepo(ReloRdfRepository _reloRDF) {
        this.reloRdf = _reloRDF;
    }
    public ReloRdfRepository getRepo() {
        return reloRdf;
    }

    
    private final List<ReloRDFBuildProcessor> buildProcessors;
    private String projectName;
    protected Resource projectResource;
    public ReloBuildVisitor(ReloRdfRepository reloRdf, List<ReloRDFBuildProcessor> buildProcessors, IProject project) {
    	this.reloRdf = reloRdf;
        this.buildProcessors = buildProcessors;

        reloRdf.startTransaction();
        this.projectName = project.getName();
        projectResource = ReloCore.eclipseProjectToRDFResource(reloRdf, project);
        reloRdf.addStatement(projectResource, reloRdf.rdfType, RJCore.projectType);
        reloRdf.addStatement(projectResource, ReloCore.name, this.projectName);
        reloRdf.addStatement(projectResource, ReloCore.initialized, true);
        reloRdf.commitTransaction();
    }
    
    public String getProjectName() {
    	return this.projectName;
    }

    public void initProcessors() {
        Artifact projArt = new Artifact(projectResource);
        for (ReloRDFBuildProcessor processor : buildProcessors) {
            processor.init(reloRdf, projArt);
        }
    }
    public void runProcessors(Resource classRes) {
    	// bug in sesame?: seems like namespaces are only saved on commitTransaction
		reloRdf.commitTransaction(); reloRdf.startTransaction(); 
        for (ReloRDFBuildProcessor processor : buildProcessors) {
            processor.process(classRes);
        }
    }
    public void finishProcessing() {
    	reloRdf.startTransaction();
        for (ReloRDFBuildProcessor processor : buildProcessors) {
            processor.finishProcessing();
        }
    	reloRdf.commitTransaction();
    }

    public abstract boolean visit(IResourceDelta delta) throws CoreException;

    public abstract boolean visit(IResource resource) throws CoreException;
    
}
